package com.android.baselibrary.base

import android.app.Activity
import android.net.Uri
import android.os.Bundle
import com.alibaba.android.arouter.facade.Postcard
import com.alibaba.android.arouter.facade.callback.NavCallback
import com.alibaba.android.arouter.launcher.ARouter
import com.android.baselibrary.app.MainApplication
import java.io.Serializable
import java.util.concurrent.ConcurrentHashMap


class CommonRouterManger private constructor() {
    companion object {
        val instance by lazy {
            CommonRouterManger()
        }
    }

    /**
     *普通跳转
     */
    fun navigationActivity(path: String) {
        ARouter.getInstance().build(path).navigation()
    }

    /**
     * INTRODUCE:回调跳转
     */
    fun navigationActivity(path: String, context: Activity, requestCode: Int, vararg params: Pair<String, Any>) {
        ARouter.getInstance().build(path).putExtras(*params).navigation(context, requestCode)
    }

    fun navigationActivity(path: String, bundle: Bundle) {
        ARouter.getInstance().build(path).withBundle("bundle_info", bundle).navigation()
    }

    /**
     * INTRODUCE:携带参数跳转,可以添加回调函数
     */
    fun navigationActivity(path: String, function: () -> Unit, vararg params: Pair<String, Any?>) {
        val navigation = ARouter.getInstance().build(path).putExtras(*params)
        navigation.navigation(MainApplication.mainApplication, object : NavCallback() {
            override fun onArrival(postcard: Postcard?) {
                function.invoke()
            }
        })
    }

    /**
     * INTRODUCE:携带参数跳转,添加拦截器失效方法
     */
    fun navigationActivityParamsGreenChannel(path: String, vararg params: Pair<String, Any>) {
        val navigation = ARouter.getInstance().build(path).putExtras(*params)
        navigation.greenChannel().navigation()
    }

    /**
     *
     */
    fun navigationActivityParams(path: String, vararg params: Pair<String, Any?>) {
        val navigation = ARouter.getInstance().build(path).putExtras(*params)
        navigation.navigation()
    }
    fun navigationActivityParamsWithFlag(path: String, flag:Int,vararg params: Pair<String, Any?>) {
        val navigation = ARouter.getInstance().build(path).putExtras(*params).withFlags(flag)
        navigation.navigation()
    }

    /**
     *
     */
    fun navigationActivityParams(path: String, context: Activity, requestCode: Int, vararg params: Pair<String, Any?>) {
        val navigation = ARouter.getInstance().build(path).putExtras(*params)
        navigation.navigation(context, requestCode)
    }

    private fun Postcard.putExtras(vararg params: Pair<String, Any?>): Postcard {
        if (params.isEmpty()) return this
        params.forEach { (key, value) ->
            when (value) {
                is Int -> withInt(key, value)
                is String -> withString(key, value)
                is Boolean -> withBoolean(key, value)
                is Char -> withChar(key, value)
                is Byte -> withByte(key, value)
                is Float -> withFloat(key, value)
                is Bundle -> withBundle(key, value)
                is Double -> withDouble(key, value)
                is ByteArray -> withByteArray(key, value)
                is Serializable -> withSerializable(key, value)
                is ArrayList<*> -> {
                    withStringArrayList(key, value as ArrayList<String>)
                }

                is Object -> withObject(key, value)
            }
        }
        return this
    }

    /**
     * 路由映射维护表
     */
    private val routeMappingMap = ConcurrentHashMap<String, String>()

    /**
     * 添加路由映射
     *
     * @param pair
     */
    fun addRouteMapping(vararg pair: Pair<String, String>) {
        //传入map使用ConcurrentHashMap的putAll方法，保证线程安全
        routeMappingMap.putAll(mapOf(*pair))
    }

    /**
     * 添加路由映射
     *
     * @param map
     */
    fun addRouteMapping(map: Map<String, String>) {
        routeMappingMap.putAll(map)
    }

    /**
     * 移除路由映射
     *
     * @param key key
     */
    fun removeRouteMapping(key: String) {
        routeMappingMap.remove(key)
    }

    /**
     * 替换映射路由
     *
     * @param uri 原uri
     * @return 替换后的uri
     */
 /*   internal fun replaceMapping(uri: Uri): Uri {
        var resultUri = uri
        if (resultUri.scheme in listOf("http", "https")) {
            // 网址转到web容器内
            resultUri = Uri.Builder().scheme("sapp").authority("app").path("webview")
                .appendQueryParameter("url", resultUri.toString())
                .build()
        }
        //非本app的scheme不再处理
        if (resultUri.scheme != "sapp") {
            val resultUriString = resultUri.toString()
            // uri不符合网址格式规则会导致ARouter解析抛异常，转为网址格式规则让此地址在ARouter内lost
            return if (!resultUriString.matches(".://././.".toRegex())) {
                Uri.Builder().scheme("sapp").authority("app").path("illegal/target/path")
                    .appendQueryParameter("url", resultUriString)
                    .build()
            } else {
                resultUri
            }
        }
        // web容器内url携带需登录参数转到登录页面
        if (resultUri.path == "/webview" && !CommonUserUtils.instance.isLogin()) {
            try {
                val webUri = Uri.parse(resultUri.getQueryParameter("url") ?: "")
                if (webUri.getQueryParameter("needLogin") == "1") {
                    return resultUri.buildUpon().clearQuery().path(CommonRouterConstant.COMMON_PATH_LOGIN_ACTIVITY).build()
                }
            } catch (ignored: Exception) {
            }
        }
        val originPath = resultUri.path ?: return resultUri
        if (originPath in routeMappingMap.keys) {
            val targetRoute = routeMappingMap[originPath] ?: return resultUri
            //对内路由有参数且对外路由也有参数,把对外路由的参数拼到对内路由上
            return if (targetRoute.contains("?") && resultUri.queryParameterNames.isNotEmpty()) {
                Uri.parse("sapp://app${targetRoute}&${resultUri.query}")
            } else {
                resultUri.buildUpon().path(targetRoute).build()
            }
        }
        return resultUri
    }*/

    /**
     * function能力路由映射表
     */
    private val routeFuncMappingMap = ConcurrentHashMap<String, (params: Map<String, String?>) -> Unit>()

    /**
     * 添加路由映射
     *
     * @param pair
     */
    fun addRouteFuncMapping(vararg pair: Pair<String, (params: Map<String, String?>) -> Unit>) {
        //传入map使用ConcurrentHashMap的putAll方法，保证线程安全
        routeFuncMappingMap.putAll(mapOf(*pair))
    }

    /**
     * 添加路由映射
     *
     * @param map
     */
    fun addRouteFuncMapping(map: Map<String, (params: Map<String, String?>) -> Unit>) {
        routeFuncMappingMap.putAll(map)
    }

    /**
     * 移除路由映射
     *
     * @param key
     */
    fun removeRouteFuncMapping(key: String) {
        routeFuncMappingMap.remove(key)
    }

    /**
     * 预处理function映射
     */
    fun preTreatMapping(uri: Uri): Boolean {
        val scheme = uri.scheme
        if (scheme!="sapp") {
            return true
        }
        val path = uri.path
        if (path != null) {
            routeFuncMappingMap[path]?.let { func ->
                func.invoke(uri.queryParameterNames.associateWith { uri.getQueryParameter(it) })
                return false
            }
        }
        return true
    }
}